package com.java80.littlegame.service.quartz;

import java.util.Date;
import java.util.concurrent.ConcurrentHashMap;

import org.quartz.CronScheduleBuilder;
import org.quartz.CronTrigger;
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.JobKey;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SchedulerFactory;
import org.quartz.SimpleTrigger;
import org.quartz.TriggerBuilder;
import org.quartz.TriggerKey;
import org.quartz.impl.StdSchedulerFactory;

public class CronTaskMgr {
	private static final String TriggerKeyProfix = "T_";

	private static final String DEFAULT_GROUP_NAME = "default_group";

	private static SchedulerFactory gSchedulerFactory;

	private static CronTaskMgr cronTaskManager = new CronTaskMgr();

	private ConcurrentHashMap<Long, CronTask> taskPool;

	public CronTaskMgr() {
		init();
		startJobs();
	}

	public static CronTaskMgr getInstance() {
		if (cronTaskManager == null)
			cronTaskManager = new CronTaskMgr();
		return cronTaskManager;
	}

	public void init() {
		try {
			gSchedulerFactory = new StdSchedulerFactory("../config/quartz.properties");

			taskPool = new ConcurrentHashMap<Long, CronTask>();

		} catch (SchedulerException e) {
			e.printStackTrace();
		}
	}

	/**
	 * 启动所有定时任务
	 */
	public void startJobs() {
		if (gSchedulerFactory != null) {
			try {
				Scheduler sched = gSchedulerFactory.getScheduler();
				sched.start();
			} catch (Exception e) {
				e.printStackTrace();
				throw new RuntimeException(e);
			}
		}
	}

	/**
	 * 关闭所有定时任务
	 */
	public void shutdownJobs() {
		if (gSchedulerFactory != null) {
			try {
				Scheduler sched = gSchedulerFactory.getScheduler();
				if (!sched.isShutdown()) {
					sched.shutdown();
				}
			} catch (Exception e) {
				e.printStackTrace();
				throw new RuntimeException(e);
			}
		}
	}

	public int getPoolTotal() {
		return taskPool.size();
	}

	/***
	 * 添加一个定时任务
	 * 
	 * @param jobName
	 *            任务名
	 * @param jobClass
	 *            任务执行类
	 * @param time
	 */
	public boolean addCountDownJob(String jobName, String groupName, CronTask task) {
		String _gName = groupName;
		if (groupName == null) {
			_gName = DEFAULT_GROUP_NAME;
		}

		// SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		// //System.out.println("### addJob taskid="+task.toString()+" at " +
		// sdf.format(new Date()) );

		try {

			Scheduler scheduler0 = gSchedulerFactory.getScheduler();

			JobDetail jd = scheduler0.getJobDetail(new JobKey(jobName, _gName));

			if (jd != null) {
				/** 停止触发器 */
				TriggerKey tk = new TriggerKey(TriggerKeyProfix + jobName, TriggerKeyProfix + _gName);
				scheduler0.pauseTrigger(tk);

				/** 移除触发器 **/
				scheduler0.unscheduleJob(tk);
				/** 删除任务 **/
				scheduler0.deleteJob(jd.getKey());
			}
		} catch (SchedulerException e1) {
			e1.printStackTrace();
			return false;
		}

		try {
			Scheduler scheduler = gSchedulerFactory.getScheduler();

			JobDetail jobDetail = JobBuilder.newJob(CronJob.class).withIdentity(jobName, _gName).build();

			jobDetail.getJobDataMap().put(CronTask.TASK_KEY, task);

			SimpleTrigger trigger = (SimpleTrigger) TriggerBuilder.newTrigger()
					.withIdentity(TriggerKeyProfix + jobName, TriggerKeyProfix + _gName)
					.startAt(new Date(task.getEndTime())).build();

			scheduler.scheduleJob(jobDetail, trigger);

			task.setDetail(this, jobDetail, trigger);

		} catch (SchedulerException e) {
			e.printStackTrace();
			return false;
		}

		taskPool.put(task.getId(), task);

		return true;
	}

	public boolean addCountDownJob(String jobName, String groupName, CronTask task, String reg) {
		try {
			Scheduler scheduler0 = gSchedulerFactory.getScheduler();
			JobDetail jd = scheduler0.getJobDetail(new JobKey(jobName, groupName));

			if (jd != null) {
				/** 停止触发器 */
				TriggerKey tk = new TriggerKey(TriggerKeyProfix + jobName, TriggerKeyProfix + groupName);
				scheduler0.pauseTrigger(tk);

				/** 移除触发器 **/
				scheduler0.unscheduleJob(tk);
				/** 删除任务 **/
				scheduler0.deleteJob(jd.getKey());
			}
		} catch (SchedulerException e1) {
			e1.printStackTrace();
			return false;
		}

		try {
			Scheduler scheduler = gSchedulerFactory.getScheduler();

			JobDetail jobDetail = JobBuilder.newJob(CronJob.class).withIdentity(jobName, groupName).build();

			jobDetail.getJobDataMap().put(CronTask.TASK_KEY_CRON, task);

			CronTrigger trigger = null;

			trigger = TriggerBuilder.newTrigger().withIdentity(TriggerKeyProfix + jobName, TriggerKeyProfix + groupName)
					.withSchedule(CronScheduleBuilder.cronSchedule(reg)).build();

			scheduler.scheduleJob(jobDetail, trigger);

			task.setDetail(this, jobDetail, trigger);

		} catch (SchedulerException e) {
			e.printStackTrace();
			return false;
		}

		taskPool.put(task.getId(), task);

		return true;
	}

	public static void main(String[] args) {
		CronTaskMgr instance = getInstance();
	}

	void removeJob(CronTask task) {
		try {
			Scheduler sched = gSchedulerFactory.getScheduler();

			/** 停止触发器 */

			sched.pauseTrigger(task.getTrigger().getKey());

			/** 移除触发器 **/
			sched.unscheduleJob(task.getTrigger().getKey());
			/** 删除任务 **/
			sched.deleteJob(task.getJobDetail().getKey());

		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public CronTask removeJob(long taskId) {
		CronTask task = taskPool.remove(taskId);
		if (task != null) {
			// SimpleDateFormat sdf = new
			// SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
			// //System.out.println("### removeJob taskid="+task.toString()+" at
			// "
			// + sdf.format(new Date()) );
			removeJob(task);
			return task;
		} else {
			// System.out.println(" error: task not found id = "+taskId);
		}
		return null;
	}
}
